home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
program
/
freeli22.zip
/
PROGS
/
SQUASH.ASM
< prev
next >
Wrap
Assembly Source File
|
1996-09-01
|
8KB
|
259 lines
; Simple executable-file compressor.
Ideal
Jumps
Public main
Extrn startup:near
Macro lcall p,a,b,c,d,e,f,g,h ;; library call
ifnb <a>
push a ;; if args, push first arg
lcall p,b,c,d,e,f,g,h ;; and recurse . . .
else
extrn p:near ;; declare procedure
call p ;; call procedure
endif
EndM
Model Tiny
Codeseg
P186
Org 100h
Start: jmp startup
;****************** Data Section
Syntax db 'Syntax: SQUASH <infile> <outfile>',0
;****************** 'main' procedure
Proc main
lcall fsetbuf 16384 ;Set file buffers to 16K
cmp cx,2 ;Wrong number of args?
jne m_syntax
lcall fopen [di],0 ;Open input file
test ax,ax ;File not found?
jz m_syntax
xchg bx,ax ;BX = handle
lcall fopen [di+2],3 ;Open output file
test ax,ax ;Check for errors
jnz m_ok1
lcall fclose bx ;Close input file
jmp m_syntax ;Go print syntax
m_ok1: xchg dx,ax ;DX = handle
push bx dx ;Encode the file
call Encode
lcall fclose bx ;Close files
lcall fclose dx
ret ;Return
m_syntax: push offset(Syntax) ;Display 'Syntax' message
lcall puts
ret ;Return
EndP main
;The decoder prefix. See the end of the file for the actual
;assembly language code used to generate this block of data.
Decoder dw 48736,354,4287,35707,6670,-3327,48804,284,191
dw 22510,185,-3327,50084
DLen dw 0 ;File length
dw 191,45295,47392,4096,43763,4286,49019,256
dw 11915,282,37292,32949,49203,53811,-3446,53386
dw -9421,-374,-5167,-9678,-6272,33807,30157
dw 44037,34696,-4352,34698,-4352,53418,29645
dw 35331,17932,30029,25049,-6401
;****************** Encode() -- Encode file
;void Encode(FILE *input, FILE *output)
input equ bp+6
output equ bp+4
Proc Encode
push bp ;Set up stack frame
mov bp,sp
pusha ;Save all registers
push es
lcall faralloc 256 ;Allocate 4K memory
test ax,ax ;Out of memory?
jz p1_quit
mov es,ax ;ES = memory
xor di,di ;Fill buffer with spaces:
mov al,20h ;the most common character
mov cx,1000h
rep stosb
lcall fseek [input],0,0,2 ;Get length
lcall ftell [input]
mov si,ax
mov [DLen],ax ;Save length
lcall fseek [input],0,0,0
push [output] ;Write out decoder
push 98
push offset(Decoder)
lcall fwrite
xor ax,ax ;Zero AX, DX, DI
xor dx,dx
xor di,di
mov cx,8000h ;CH = bit mask, CL = buffer
p1_loop: mov dh,dl ;Shift prev-chars
mov dl,al
lcall fgetc [input] ;Load char
xor bx,bx ;Convert to 4K index
mov bh,dh
shr bx,1
xor bl,dl
and bh,0Fh
cmp al,[es:bx] ;Predicted it?
jne p1_char
or cl,ch ;Set predict bit
jmp p1_cont
p1_char: mov [es:bx],al ;Set prediction
mov [p1_buf+di],al ;Add char to buffer
inc di
p1_cont: shr ch,1 ;Next bit
jnz p1_lb
push ax ;Save AX
lcall fputc [output],cx ;Output bit byte
xor bx,bx ;Zero BX
mov cx,di ;No chars?
jcxz p1_cont2
p1_bloop: push [output] ;Output char
push [word p1_buf+bx]
lcall fputc
inc bx ;Next char
loop p1_bloop ;Loop back
p1_cont2: mov cx,8000h ;Re-init bit buffer
xor di,di
pop ax ;Restore AX
p1_lb: dec si ;Loop back
jnz p1_loop
cmp cx,8000h ;Nothing, quit
je p1_done
lcall fputc [output],cx ;Output final flags
xor bx,bx ;Zero BX
mov cx,di ;No chars?
jcxz p1_done
p1_bloop2: push [output] ;Output char
push [word p1_buf+bx]
lcall fputc
inc bx ;Next char
loop p1_bloop2 ;Loop back
p1_done: lcall farfree es ;Free the memory
p1_quit: pop es ;Restore registers
popa
pop bp ;Delete stack frame
ret 4 ;Return
p1_buf db 8 dup(0)
EndP Encode
End Start
; The executable decoder (98 bytes). Decodes files up to
; 30K in length (after decoding). Assumes SI = IP at start.
; Start: pusha ;Save all registers
;
; mov si,offset Buffer ;Relocate data buffer
; mov di,31504
; mov cx,[dlen]
; rep movsb
;
; mov si,offset Decode ;Relocate decoder
; mov di,0EE00h
; push di
; mov cx,256
; rep movsb
;
; ret ;Jump to decode code
;
; dlen dw 0 ;Length of file
;
; Decode: mov di,0EF00h ;Fill buffer with spaces:
; mov al,20h ;the most common character
; mov cx,1000h
; rep stosb
;
; mov si,31504 ;SI = buffer, DI = start point
; mov di,0100h
;
; mov bp,[dlen] ;BP = length
;
; lodsb ;Init bit buffer
; xchg cx,ax
; mov ch,80h
;
; xor ax,ax ;Zero AX, DX
; xor dx,dx
;
; DecLoop: mov dh,dl ;Shift prev-chars
; mov dl,al
;
; xor bx,bx ;Convert to 4K index
; mov bh,dh
; shr bx,1
; xor bl,dl
; and bh,0Fh
;
; test cl,ch ;Check predict bit
; jnz DecSkip
;
; lodsb ;Wrong, set prediction
; mov [bx+0EF00h],al
;
; DecSkip: mov al,[bx+0EF00h] ;Get prediction
; stosb ;Output char
;
; ror ch,1 ;Rotate mask
; jnc $+5 ;Check for wrap
; mov cl,[si] ;Load flag byte in CL
; inc si
;
; dec bp ;Loop back
; jnz DecLoop
;
; popa ;Restore registers
; jmp si ;Jump to start
;
; Buffer: